﻿using System;
using System.Drawing;
using OpenCvSharp;
using OpenCvSharp.Extensions;
using Point = OpenCvSharp.Point;

namespace Nero_demo
{
    public class ImageSearcher
    {
        public static bool FindImage(string sourcePath, string templatePath, out System.Drawing.Point targetPoint, double threshold = 0.75, bool debug = false)
        {
            Mat source = new Mat(sourcePath, ImreadModes.Color);
            return FindImage(source, templatePath, out targetPoint, threshold, debug);
        }

        public static bool FindImage(Mat source, string templatePath, out System.Drawing.Point targetPoint, double threshold = 0.75, bool debug = false)
        {
            Mat template = new Mat(templatePath, ImreadModes.Color);

            double maxVal;
            MatchImage(out targetPoint, debug, source, template, out maxVal);

            source.Release();
            template.Release();

            source.Dispose();
            template.Dispose();

            GC.Collect();

            return maxVal > threshold;
        }

        private static void MatchImage(out System.Drawing.Point targetPoint, bool debug, Mat source, Mat template, out double maxVal)
        {
            Mat result = new Mat();
            Cv2.MatchTemplate(source, template, result, TemplateMatchModes.CCoeffNormed); //进行匹配

            double minVal;
            Point minLoc, maxLoc;
            Cv2.MinMaxLoc(result, out minVal, out maxVal, out minLoc, out maxLoc); //找到最大相似度

            targetPoint = new System.Drawing.Point(maxLoc.X + template.Width / 2, maxLoc.Y + template.Height / 2); //取中心点

            if (debug)
            {
                Cv2.Rectangle(source, maxLoc, new Point(maxLoc.X + template.Width, maxLoc.Y + template.Height), new Scalar(0, 255, 0), 2);
                Cv2.PutText(source, maxVal.ToString("F4"), new Point(maxLoc.X, maxLoc.Y - 10), HersheyFonts.HersheyPlain, 2, new Scalar(255, 0, 0));
                Cv2.ImShow("匹配结果", source);
                Cv2.WaitKey(0);
            }

            result.Release();
            result.Dispose();
        }
    }
}
